﻿using Common.Extension;

namespace DesignModeConsole.行为型.解释器模式.告警规则简单;

/// <summary>
/// 告警表达式
/// </summary>
public interface IAlertRuleExpression1
{
    bool Interpret(Dictionary<string, long> stats);
}

/// <summary>
/// 大于表达式
/// </summary>
public class DaYuExpression1 : IAlertRuleExpression1
{
    private readonly string _key;
    private readonly long _value;

    public DaYuExpression1(string key, long value)
    {
        _key = key;
        _value = value;
    }

    public DaYuExpression1(string expression)
    {
        var elements = expression.Trim().Split(" ");
        if (elements.Length != 3 || !elements[1].Trim().Equals(">"))
        {
            throw new ArgumentException("无效的表达式");
        }

        _key = elements[0].Trim();
        _value = elements[2].Trim().ToInt64();
    }

    public bool Interpret(Dictionary<string, long> stats)
    {
        if (!stats.TryGetValue(_key, out var value))
            return false;

        var statValue = value;
        return statValue > _value;
    }
}

/// <summary>
/// 小于
/// </summary>
public class XiaoYuExpression1 : IAlertRuleExpression1
{
    private readonly string _key;
    private readonly long _value;

    public XiaoYuExpression1(string key, long value)
    {
        _key = key;
        _value = value;
    }

    public XiaoYuExpression1(string expression)
    {
        var elements = expression.Trim().Split(" ");
        if (elements.Length != 3 || !elements[1].Trim().Equals("<"))
        {
            throw new ArgumentException("无效的表达式");
        }

        _key = elements[0].Trim();
        _value = elements[2].Trim().ToInt64();
    }

    public bool Interpret(Dictionary<string, long> stats)
    {
        if (!stats.TryGetValue(_key, out var value))
            return false;

        var statValue = value;
        return statValue < _value;
    }
}

/// <summary>
/// 等于表达式
/// </summary>
public class EqualExpression1 : IAlertRuleExpression1
{
    private readonly string _key;
    private readonly long _value;

    public EqualExpression1(string key, long value)
    {
        _key = key;
        _value = value;
    }

    public EqualExpression1(string expression)
    {
        var elements = expression.Trim().Split(" ");
        if (elements.Length != 3 || !elements[1].Trim().Equals("="))
        {
            throw new ArgumentException("无效的表达式");
        }

        _key = elements[0].Trim();
        _value = elements[2].Trim().ToInt64();
    }

    public bool Interpret(Dictionary<string, long> stats)
    {
        if (!stats.TryGetValue(_key, out var value))
            return false;

        var statValue = value;
        return statValue == _value;
    }
}

/// <summary>
/// and 表达式
/// </summary>
public class AndExpression1 : IAlertRuleExpression1
{
    private readonly List<IAlertRuleExpression1> _expressions = new List<IAlertRuleExpression1>();

    public AndExpression1(string strAndExpression)
    {
        var strExpressions = strAndExpression.Split("&&");
        foreach (var e in strExpressions)
        {
            if (e.Contains(">"))
            {
                _expressions.Add(new DaYuExpression1(e));
            }
            else if (e.Contains("<"))
            {
                _expressions.Add(new XiaoYuExpression1(e));
            }
            else if (e.Contains("="))
            {
                _expressions.Add(new EqualExpression1(e));
            }
            else
            {
                throw new ArgumentException("表达式无效");
            }
        }
    }

    public AndExpression1(List<IAlertRuleExpression1> expressions)
    {
        _expressions.AddRange(expressions);
    }

    public bool Interpret(Dictionary<string, long> stats)
    {
        foreach (var item in _expressions)
        {
            if (!item.Interpret(stats))
            {
                return false;
            }
        }

        return true;
    }
}

/// <summary>
/// or 表达式
/// </summary>
public class OrExpression1 : IAlertRuleExpression1
{
    private readonly List<IAlertRuleExpression1> _expressions = new List<IAlertRuleExpression1>();

    public OrExpression1(string strOrExpression)
    {
        var andExpressions = strOrExpression.Split("||");
        foreach (var andExpr in andExpressions)
        {
            _expressions.Add(new AndExpression1(andExpr));
        }
    }

    public OrExpression1(List<IAlertRuleExpression1> expressions)
    {
        _expressions.AddRange(expressions);
    }

    public bool Interpret(Dictionary<string, long> stats)
    {
        foreach (var item in _expressions)
        {
            if (item.Interpret(stats))
            {
                return true;
            }
        }
        return false;
    }
}